package com.colorful.insuranceproject.base;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.LocationSource;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.model.CameraPosition;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.colorful.insuranceproject.R;
import com.colorful.insuranceproject.utils.BaiDuGeoCoder;
import com.lovely3x.common.activities.CommonActivity;
import com.lovely3x.common.beans.LocationWrapper;
import com.lovely3x.common.utils.ALog;
import com.lovely3x.common.utils.LatLngTransformUtils;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * {@link #EXTRA_LOCATION }如果用户选择了一个位置的话，那么你可以在{@link #onActivityResult(int, int, Intent)}中通过这{@link Intent#getParcelableExtra(String)}
 * 获取到用户选择的位置
 * <br/>
 * 如果你想指定用户进入这个界面时的位置，你可以使用{@link #EXTRA_DEFAULT_LOCATION}传递一个默认的位置{@link android.location.Location}
 * 地图界面
 * Created by lovely3x on 15-12-4.
 */
public class MapActivity extends TitleActivity implements LocationSource, AMapLocationListener {

    /**
     * 获取用户选择结果的key
     */
    public static final String EXTRA_LOCATION = "extra.location";
    /**
     * 默认的位置的key
     */
    public static final String EXTRA_DEFAULT_LOCATION = "extra.default.location";
    /**
     * 搜索位置的请求码
     */
    private static final int REQUEST_CODE_SEARCH_LOCATION = 0x39;

    private static final String TAG = "MapActivity";

    @Bind(R.id.mv_activity_map)
    MapView mapView;

    /**
     * 内容区容器
     */
    @Bind(R.id.ll_activity_map_content_container)
    LinearLayout contentContainer;

    /**
     * 选择这里
     */
    @Bind(R.id.tv_activity_map_select_there)
    TextView tvSelect;

    /**
     * 区县
     */
    @Bind(R.id.tv_activity_map_district)
    TextView tvDistrict;

    /**
     * 详细地址
     */
    @Bind(R.id.tv_activity_map_address_details)
    TextView tvAddressDetails;

    private AMap aMap;
    private LocationSource.OnLocationChangedListener mListener;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;
    private GeocodeSearch geocoderSearch;

    public static void launchMeForResult(CommonActivity activity, LocationWrapper defaultLocation, int requestCode) {
        Intent intent = makeIntent(activity, defaultLocation);
        activity.startActivityForResult(intent, requestCode);
    }

    public static void launchMe(CommonActivity activity, LocationWrapper defaultLocation) {
        Intent intent = makeIntent(activity, defaultLocation);
        activity.startActivity(intent);
    }

    private static Intent makeIntent(CommonActivity activity, LocationWrapper defaultLocation) {
        Intent intent = new Intent(activity, MapActivity.class);
        if (defaultLocation != null) {
            intent.putExtra(EXTRA_DEFAULT_LOCATION, defaultLocation);
        }
        return intent;
    }

    public static LocationWrapper getChoiceLocation(Intent data) {
        if (data == null) return null;
        return data.getParcelableExtra(EXTRA_LOCATION);
    }

    /**
     * 用户选择的位置
     */
    private LocationWrapper mSelectedAddress;
    /**
     * 进入默认的位置
     */
    private LocationWrapper mDefaultLocation;

    private Handler mHandler;

    @Override
    protected void onInitExtras(@NonNull Bundle bundle) {
        super.onInitExtras(bundle);
        mDefaultLocation = bundle.getParcelable(EXTRA_DEFAULT_LOCATION);
    }

    @Override
    protected int getContentView() {
        return R.layout.activity_map;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (mapView != null) {
            mapView.onCreate(savedInstanceState);// 此方法必须重写
        }
        init();
    }

    @Override
    protected void initViews() {
        ButterKnife.bind(this);
        setTitle(R.string.location_choice);
        getIvBack().setImageResource(R.drawable.icon_close_white);

        mHandler = new Handler();
        contentContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    contentContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    contentContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }

                int height = contentContainer.getHeight();
                FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) contentContainer.getLayoutParams();
                lp.bottomMargin = height / 2;
                contentContainer.setLayoutParams(lp);
            }
        });
    }

    /**
     * 视图初始化完成
     * 这个方法执行完成之后将立即执行{@link #restoreInstanceOnCreateAfter(Bundle)}
     */
    @Override
    protected void onViewInitialized() {

    }

    @Override
    public void restoreInstanceOnCreateBefore(@NonNull Bundle savedInstance) {

    }

    @Override
    public void restoreInstanceOnCreateAfter(@NonNull Bundle savedInstance) {

    }

    /**
     * 初始化AMap对象
     */
    private void init() {
        if (aMap == null) {
            aMap = mapView.getMap();
            setUpMap();
        }
    }

    /**
     * 设置一些amap的属性
     */
    private void setUpMap() {
        aMap.setLocationSource(this);// 设置定位监听
        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        geocoderSearch = new GeocodeSearch(this);
        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {

            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {
                LatLng target = cameraPosition.target;
                LatLonPoint llp = new LatLonPoint(target.latitude, target.longitude);
                reGeoQuery(llp);
                com.lovely3x.common.beans.LatLng wgs84 = LatLngTransformUtils.gcj_To_84(target.latitude, target.longitude);
                BaiDuGeoCoder.reGeo(wgs84, new BaiDuGeoCoder.CallBack() {
                    @Override
                    public void onResult(final LocationWrapper locationWrapper, final Exception e) {
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {

                                if (e == null && locationWrapper != null) {
                                    MapActivity.this.mSelectedAddress = locationWrapper;
                                    double lat = locationWrapper.getLatitude();
                                    double lng = locationWrapper.getLongitude();
                                    com.lovely3x.common.beans.LatLng transformResult = LatLngTransformUtils.LatLng84_To_Gcj02(lat, lng);
                                    locationWrapper.setLatitude(transformResult.lat);
                                    locationWrapper.setLongitude(transformResult.lng);

                                    String district = locationWrapper.getDistrict();
                                    String city = locationWrapper.getCity();
                                    String province = locationWrapper.getProvince();
                                    String displayTitle = TextUtils.isEmpty(district) ? (TextUtils.isEmpty(city) ? province : city) : district;
                                    if (TextUtils.isEmpty(displayTitle))
                                        displayTitle = getString(R.string.can_not_find_you);

                                    if (tvAddressDetails != null) {
                                        tvDistrict.setText(displayTitle);
                                        tvAddressDetails.setText(TextUtils.isEmpty(locationWrapper.getQualifiedName())
                                                ? getString(R.string.can_not_find_your_location) : locationWrapper.getQualifiedName());
                                    }

                                } else {
                                    //转换失败
                                    tvDistrict.setText(R.string.can_not_find_you);
                                    tvAddressDetails.setText(R.string.can_not_find_your_location);
                                }
                            }
                        });
                    }
                });
            }
        });
        //移动相机的作坊等级到最大
        aMap.moveCamera(CameraUpdateFactory.zoomTo(aMap.getMaxZoomLevel()));

        // move map camera to spc location.
        if (mDefaultLocation != null) {
            if (mDefaultLocation.getLongitude() != -1 && mDefaultLocation.getLatitude() != -1) {
                aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mDefaultLocation.getLatitude(), mDefaultLocation.getLongitude()), aMap.getMaxZoomLevel()));
            }
        }
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onResume() {
        super.onResume();
        if (mapView != null) {
            mapView.onResume();
        }
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onPause() {
        super.onPause();
        if (mapView != null) {
            mapView.onPause();
        }
        deactivate();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mapView != null) {
            mapView.onSaveInstanceState(outState);
        }
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mapView != null) {
            mapView.onDestroy();
        }
    }


    /**
     * 定位成功后回调函数
     */
    @Override
    public void onLocationChanged(final AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation.getErrorCode() == 0) {
                mListener.onLocationChanged(amapLocation);// 显示系统小蓝点
                //当用户没有主动选择位置，或主动选择的位置为null才变化
                if (mSelectedAddress == null && mDefaultLocation == null) {
                    mSelectedAddress = new LocationWrapper();
                    mSelectedAddress.setDistrict(amapLocation.getDistrict());
                    mSelectedAddress.setCity(amapLocation.getCity());
                    mSelectedAddress.setProvince(amapLocation.getProvince());
                    mSelectedAddress.setQualifiedName(amapLocation.getAddress());
                    mSelectedAddress.setLatitude(amapLocation.getLatitude());
                    mSelectedAddress.setLongitude(amapLocation.getLongitude());

                    String district = amapLocation.getDistrict();
                    String city = amapLocation.getCity();
                    String province = amapLocation.getProvince();
                    String displayTitle = TextUtils.isEmpty(district) ? (TextUtils.isEmpty(city) ? province : city) : district;
                    if (TextUtils.isEmpty(displayTitle))
                        displayTitle = getString(R.string.can_not_find_you);
                    ALog.e(TAG, amapLocation.getAddress());

                    if (tvAddressDetails != null) {
                        tvDistrict.setText(displayTitle);
                        tvAddressDetails.setText(TextUtils.isEmpty(amapLocation.getAddress())
                                ? getString(R.string.can_not_find_your_location) : amapLocation.getAddress());
                    }
                    aMap.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.builder()
                            .zoom(aMap.getCameraPosition().zoom)
                            .tilt(aMap.getCameraPosition().tilt)
                            .bearing(aMap.getCameraPosition().bearing)
                            .target(new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude())).build()));

                }

            } else {
                String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
                ALog.e("AmapErr", errText);
            }
        }
    }

    /**
     * 激活定位
     */
    @Override
    public void activate(LocationSource.OnLocationChangedListener listener) {
        mListener = listener;
        if (mlocationClient == null) {
            mlocationClient = new AMapLocationClient(this);
            mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mlocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位参数
            mlocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mlocationClient.startLocation();
        }
    }

    private void reGeoQuery(final LatLonPoint latLng) {
        // 第一个参数表示一个Latlng，第二参数表示范围多少米，第三个参数表示是火系坐标系还是GPS原生坐标系
        RegeocodeQuery query = new RegeocodeQuery(latLng, 0, GeocodeSearch.AMAP);
        geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
                RegeocodeAddress address = regeocodeResult.getRegeocodeAddress();
                //mSelectedAddress = null;
                if (address != null) {

                    mSelectedAddress = new LocationWrapper();

                    mSelectedAddress.setDistrict(address.getDistrict());
                    mSelectedAddress.setCity(address.getCity());
                    mSelectedAddress.setProvince(address.getProvince());
                    mSelectedAddress.setQualifiedName(address.getFormatAddress());
                    mSelectedAddress.setLatitude(latLng.getLatitude());
                    mSelectedAddress.setLongitude(latLng.getLongitude());

                    String district = address.getDistrict();
                    String city = address.getCity();
                    String province = address.getProvince();
                    String displayTitle = TextUtils.isEmpty(district) ? (TextUtils.isEmpty(city) ? province : city) : district;
                    if (TextUtils.isEmpty(displayTitle))
                        displayTitle = getString(R.string.can_not_find_you);
                    ALog.e(TAG, address.getFormatAddress());
                    if (tvAddressDetails != null) {
                        tvDistrict.setText(displayTitle);
                        tvAddressDetails.setText(TextUtils.isEmpty(address.getFormatAddress())
                                ? getString(R.string.can_not_find_your_location) : address.getFormatAddress());
                    }
                }
            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

            }
        });
        geocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求
    }


    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }

    @OnClick({R.id.tv_activity_map_select_there})
    public void onSelectClicked() {
        if (mSelectedAddress == null) {
            new AlertDialog.Builder(this)
                    .setTitle(R.string.alert)
                    .setMessage(R.string.you_do_not_select_any_location)
                    .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            setResult(RESULT_CANCELED);
                            finish();
                        }
                    })
                    .setNegativeButton(R.string.cancel, null)
                    .show();
        } else {
            // TODO: 2016/12/1  
            Intent intent = new Intent();
            intent.putExtra(EXTRA_LOCATION, mSelectedAddress);
            setResult(RESULT_OK, intent);
            finish();
        }
    }

}
